package com.uchiha.nova.mainService.provider;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uchiha.nova.mainService.listener.MyRedisSubscribeListener;
import com.uchiha.nova.mainService.props.AuthProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.AntPathMatcher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author 周林静
 * @Date 2022-12-31,0031 21:41
 * @Version 1.0
 */
@Slf4j
public class GatewayUtil {
    public static boolean isSkip(String path, AuthProperties authProperties) {

        AntPathMatcher antPathMatcher=new AntPathMatcher();
        List<String> defaultSkipUrls= AuthProvider.getDefaultSkipUrl();
        List<String> skipurls = authProperties.getSkipUrl();
        boolean hasPermission=false;
        for (int i = 0; i <defaultSkipUrls.size() ; i++) {
            String roleHasPer = defaultSkipUrls.get(i);
            if(antPathMatcher.match(roleHasPer,path))
            {
                hasPermission=true;
                break;
            }
        }
        for (int i = 0; i <skipurls.size() ; i++) {
            String roleHasPer = skipurls.get(i);
            if(antPathMatcher.match(roleHasPer,path))
            {
                hasPermission=true;
                break;
            }
        }

        return hasPermission;
    }
    public static Mono<Void> noClient(ServerHttpResponse resp, String msg, ObjectMapper objectMapper) {
        resp.setStatusCode(HttpStatus.UNAUTHORIZED);
        resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        String result = "";
        try {
            result = objectMapper.writeValueAsString(ResponseProvider.unAuth(msg));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage(), e);
        }
        DataBuffer buffer = resp.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
        return resp.writeWith(Flux.just(buffer));
    }

    public static Mono<Void> errorClient(ServerHttpResponse resp, String msg,ObjectMapper objectMapper) {
        resp.setStatusCode(HttpStatus.FORBIDDEN);
        resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        String result = "";
        try {
            result = objectMapper.writeValueAsString(ResponseProvider.unAuth(msg));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage(), e);
        }
        DataBuffer buffer = resp.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
        return resp.writeWith(Flux.just(buffer));
    }

    public static  boolean isRoleHasPer(String path, String role, RedisTemplate<String, Object> redisTemplate) {
        AntPathMatcher antPathMatcher=new AntPathMatcher();
        boolean hasPermission=false;
        List<String> roleHasPers = MyRedisSubscribeListener.getRoles().get(role);
        if(roleHasPers==null){
            roleHasPers = (List<String>) redisTemplate.opsForValue().get("nova:service:"+role);
        }
        //List<String> roleHasPers = (List<String>) redisTemplate.opsForValue().get("nova:service:"+role);
        for (int i = 0; i <roleHasPers.size() ; i++) {
            String roleHasPer = roleHasPers.get(i);
            if(antPathMatcher.match(roleHasPer,path))
            {
                hasPermission=true;
                break;
            }
        }
        log.info("isRoleHasPerhasPermission:{}",hasPermission);
        return hasPermission;
    }

    public static Mono<Void> unAuth(ServerHttpResponse resp, String msg, ObjectMapper objectMapper) {
        resp.setStatusCode(HttpStatus.UNAUTHORIZED);
        resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        String result = "";
        try {
            result = objectMapper.writeValueAsString(ResponseProvider.unAuth(msg));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage(), e);
        }
        DataBuffer buffer = resp.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
        return resp.writeWith(Flux.just(buffer));
    }
    public static  Mono<Void> expressAuth(ServerHttpResponse resp, String msg, ObjectMapper objectMapper) {
        resp.setStatusCode(HttpStatus.FORBIDDEN);
        resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        String result = "";
        try {
            result = objectMapper.writeValueAsString(ResponseProvider.unAuth(msg));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage(), e);
        }
        DataBuffer buffer = resp.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
        return resp.writeWith(Flux.just(buffer));
    }
}
